ノーコードツールで作成したいHTMLソースをサムネイル目的で画像にして保存したいという話があり、いろいろ検討したのでそのメモ書きです。
同じ事をしようとしている人のために最初に結論を書いておくと、レンタルサーバー(共用サーバー)ではかなり難しいです。VPSを使うなら難OK。
共用サーバー縛りがある場合は、外部のサービス(https://htmlcsstoimage.com/ など)を使う方が楽なのかなと思います。
方法の比較
今回はいろいろ検討したのですが、大きく分けて2パターンあります。
mpdfやTCPDFなどライブラリ不要のPDF化ツールを使う
こちらは一旦HTMLをPDFに変換後、それを画像に変換します。
HTML→PDFへの変換にはmpdfやTCPDF、domPDFといったライブラリを使い、そこで出力されたPFDをImageMagickを使って画像に変換してやります。
メリット
- PHPのみで完結するため導入が比較的簡単。
- WordPressならプラグイン化していろいろなサイトに使える
デメリット
- HTMLの再現性が(とんでもなく)低い
ライブラリに癖に合わせてHTMLとCSSを調整すれば対応できますが、今回はノーコードツールで作ったHTMLを画像化したいのでCSSの調整はできません。そして許容できないぐらいレイアウトが崩れるので却下となりました。
ヘッドレスChromeを使う
ヘッドレスChromeでHTMLをレンダリングし、それをスクショすることで画像を取得します。
今回使用したのはこれ↓
https://github.com/chrome-php/chrome
メリット
- レイアウトが正確に再現できる
- スクリーンショット機能で簡単に画像を作成できる
デメリット
- サーバーにヘッドレスChromeをインストールする必要がある
ローカル環境でテストしたときはバッチリだったのですが、レンタルサーバー上ではヘッドレスChromeをインストールできないため動きません。
VPSなら簡単にインストールできると思うのですが、共用サーバーはroot権限がなくなかなか大変です。
色々試してみたのですが、私の知識では上手く動かすことができませんでした。ここを解決できたらこの方法がベストだと思います。
mpdfを使う場合のコード
mpdfを使うコードは下記になります。TCPDFなども同じような感じになると思います。
まずcomposerを使ってmpdfをインストール
$ composer require mpdf/mpdf
下記のコードでPDFを生成後、jpg画像にしています。
// PDFの生成
$mpdf = new \Mpdf\Mpdf(
array(
'mode' => 'ja',
'format' => 'A4',
'orientation' => 'P',
'fontDir' => 'path/to/ipafonts',
'fontdata' => array(
'ipaexg' => array(
'R' => 'ipaexg.ttf',
),
),
'default_font' => 'ipaexg',
)
);
$html="<p>hello world</p>";
$mpdf->WriteHTML( $html );
$file = FILE_PATH . '/thumb.pdf';
$mpdf->OutputFile( $file );
// ここから画像の生成
$im = new Imagick();
//生成したPDFを読み込む
$im->readImage($file);
// 1ページ目のみ使う
$im->setImageIndex(0);
//サムネイルサイズを幅600pxにする
$im->thumbnailImage(600, 0, true);
//保存
$im->writeImage( FILE_PATH .'/thumb.jpg');
$im->destroy();
日本語フォントはIPAexフォントを指定します。ダウンロードは下記サイトよりできます。
今回はテスト的に試しただけですが、縦に長いHTMLの場合、ページ分割なども考慮する必要がありそうな気がします。
そう考えるとこの方法はやはり筋が悪そうですね。
ヘッドレスChromeを使う場合
composerを使ってchrome-php/chromeをインストール
$ composer require chrome-php/chrome
下記のコードで、600×1000のスクリーンショット画像を保存できます。
use HeadlessChromium\BrowserFactory;
$browser_factory = new BrowserFactory();
$browser = $browser_factory->createBrowser(
array( 'windowSize' => array( 600, 1000 ) )
);
$html="<p>hello world</p>";
$file = FILE_PATH . '/thumb.png';
try {
$page = $browser->createPage();
$page->setHtml( $html );
$screenshot = $page->screenshot([
'format' => 'jpeg', // デフォルトは'png' 設定可能なフォーマット: 'png', 'jpeg', 'webp'
'quality' => 80, // 'jpeg' または 'webp' の時に指定可能 デフォルトは 100
'optimizeForSpeed' => true // デフォルトは 'false' trueだとサイズより速度優先でエンコーディングする
]);
$screenshot->saveToFile( $file );
} finally {
$browser->close();
}
オプションの設定次第でページ全体だったり一部をクリップしたスクリーンショットを生成することもできます。とっても便利。
さらにPDFへの変換もできるので開発が終了したwkhtmltopdfの代わりにはもってこいなのではないでしょうか?
レンタルサーバーにインストールはまた時間があるときに挑戦してみたいと思います。
おまけ
結局どうしたのかというと、生成が必要数も非常に少ないので外部のAPIサービスと連携することになりました。
コメント
この記事へのコメントはありません。